package com.zijiebutiao.config;


import com.fasterxml.jackson.databind.ObjectMapper;
import com.zijiebutiao.filter.JwtFilter;
import com.zijiebutiao.utils.ResultVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;


import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


/**
 * @Date 2023/2/17 19:40
 * @Author 时间刺客
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private JwtFilter jwtFilter;



    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //自定义配置

        //1.关闭csrf跨站伪造请求
        //security认为只要不是它本身提供的页面资源，就是非法的
        http.csrf().disable();
        //放开对frame帧标签的支持
        http.headers().frameOptions().disable();
        //7.处理403没有权限
        http.exceptionHandling().accessDeniedHandler(new AccessDeniedHandler() {
            @Override
            public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException, IOException {
                response.setContentType("application/json;charset=utf-8");
                ResultVo jsonResult=new ResultVo();
                jsonResult.setCode(403);
                jsonResult.setErrorMsg("权限不足");
                ObjectMapper objectMapper=new ObjectMapper();
                String json=  objectMapper.writeValueAsString(jsonResult);
                response.getWriter().print(json);
            }
        });
        //没有登陆token
//        http.exceptionHandling().authenticationEntryPoint(new AuthenticationEntryPoint() {
//            @Override
//            public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
//                //访问资源时，如果是未登录状态，需要告诉页面我们自定义的数据，而不是提示403状态码
//                //提示重新登录
//                response.setContentType("application/json;charset=utf-8");
//                ResultVo jsonResult=new ResultVo();
//                jsonResult.setCode(10010);
//                jsonResult.setErrorMsg("认证失败");
//                ObjectMapper objectMapper=new ObjectMapper();
//                String json=  objectMapper.writeValueAsString(jsonResult);
//                response.getWriter().print(json);
//            }
//        });
        //2.自定义登录表单
        http.formLogin().disable();
        http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);

        //4.指定放行的资源。要写在所有认证通过的请求前面
        http.authorizeRequests()
//                指定放行资源的规则
                .antMatchers("/dologin","/code","/kaptcha","/favicon.ico",
                        "/doc.html",
                        "/swagger-ui.html",
                        "/webjars/**",
                        "/swagger-resources/**",
                        "/v2/api-docs/**")
                .permitAll();

//        //6.基于权限控制访问权限
//        http.authorizeRequests()
//                //具备 student_update 权限 才能/student/update 的资源。
//                .antMatchers("/student/update")
//                .hasAuthority("student_update");
//
//        //5.基于角色控制访问权限
//        http.authorizeRequests()
//                //具备 javaee 或者 xiaoban 这个角色才能访问 /student/** 的资源。
//                .antMatchers("/student/**")
//                .hasAnyRole("xiaoban", "javaee");  //在这个API中会自动帮我们加上 ROLE_ 前缀
//        //如果没有对应的角色，就无法访问到目标资源，会报 403 【权限不足】


        //3.拦截规则【一定要指定】
        http.authorizeRequests()
                //任意请求
                .anyRequest()
                //认证通过
                .authenticated();
    }
}
